﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using UniversityRatingSystem.Models;
using log4net;
using UniversityRatingSystem.DependencyInjector;

namespace UniversityRatingSystem.Controllers
{
    [Authorize]
    public class ApplicationLogicController : Controller
    {
        public ApplicationDbContext AppDb { get; private set; }
        public UserManager<ApplicationUser> UserManager { get; private set; }

        public ApplicationLogicController(ApplicationDbContext appDb)
        {
            AppDb = appDb;
            UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(DI.Singleton.ApplicationDbContext));
        }

        public ApplicationLogicController():
            this(DI.Singleton.ApplicationDbContext)
        {

        }

        //
        // GET: /ApplicationLogic/
        public ActionResult Index()
        {
            var roles = "";
            foreach(var i in UserManager.GetRoles(User.Identity.GetUserId()))
            {
                roles += i + ", ";
            }
            ViewBag.userRoles = roles;
            return View();
        }

        //Shows documents associated with current user
        public ActionResult ShowDocuments()
        {
            if (User.IsInRole("student") || User.IsInRole("starosta"))
            {
                string id = UserManager.FindByName(User.Identity.Name).Id;
                var q = from doc in
                            (from person in
                                 (from person in AppDb.Persons where person.AppUserId == id select person)
                             join grp in AppDb.Groups on person.Group equals grp
                             select new { Group = grp })
                        join dox in AppDb.Documents on doc.Group equals dox.Group
                        select new { Document = dox };
                List<Document> docs = new List<Document>();
                foreach (var i in q)
                {
                    docs.Add(i.Document);
                }
                return View(docs);
            }
            else
            {
                var q = from doc in AppDb.Documents where doc.Creator.UserName == User.Identity.Name select doc;
                return View(q.ToList());
            }
        }

        public ActionResult DocumentDetails(int id)
        {
            return View((from doc in AppDb.Documents where doc.DocumentId == id select doc).First());
        }

        public ActionResult DocumentCreateStep1()
        {
            return View();
        }

        [HttpPost]
        public ActionResult DocumentCreateStep1(DocumentStep1ViewModel model)
        {
            var q = from g in AppDb.Groups where g.Name == model.Group select g;
            if(q.Count() > 0)
                return RedirectToAction("DocumentCreateStep2", new { title = model.Title, group = model.Group, count = model.ColumnCount });
            else
            {
                ModelState.AddModelError("Group", "Group does not exist");
                return View();
            }
        }

        public ActionResult DocumentCreateStep2(string title, string group, int count)
        {
            List<ColumnDataInViewModel> list = new List<ColumnDataInViewModel>(count);
            for(int i=0; i<count; i++)
            {
                list.Add(new ColumnDataInViewModel(){
                    Name = "",
                    Rating = false,
                    Summary = false,
                    MaxMark = 5
                });
            }
            ViewBag.title = title;
            ViewBag.group = group;
            return View(list);
        }

        [HttpPost]
        public ActionResult DocumentCreateStep2(string title, string groupName, List<ColumnDataInViewModel> model)
        {
            //Compute result column for database table
            int index = 1;
            string resultColumn = "";
            foreach(var col in model)
            {
                string data = index + "?" + col.Name + "?" + col.MaxMark;
                if (col.Rating)
                    data += "?1";
                else
                    data += "?0";
                if (col.Summary)
                    data += "?1";
                else
                    data += "?0";
                if (resultColumn.Length == 0)
                    resultColumn = data;
                else
                    resultColumn += ";" + data;
                index++;
            }
            //Find creator
            var appUser = UserManager.FindById(User.Identity.GetUserId());
            //Find group
            Group grp = null;
            foreach(var g in (from gr in AppDb.Groups where gr.Name == groupName select gr))
            {
                grp = g;
            }
            Document doc = new Document()
            {
                Columns = resultColumn,
                Created = DateTime.Now,
                Updated = DateTime.Now,
                Creator = appUser,
                Group = grp,
                Title = title,
            };
            //Save changes
            AppDb.Documents.Add(doc);
            AppDb.SaveChanges();
            return View();
        }

        public ActionResult EditDocument(int docId)
        {
            ViewBag.doc = AppDb.Documents.Find(docId);
            return View(ConvertFromStringToColumns(ViewBag.doc.Columns));
        }

        private List<ColumnDataInViewModel> ConvertFromStringToColumns(String columnSource)
        {
            string[] cols = columnSource.Split(';');
            List<ColumnDataInViewModel> result = new List<ColumnDataInViewModel>(cols.Length);
            foreach(var column in columnSource.Split(';'))
            {
                string[] data = column.Split('?');
                ColumnDataInViewModel col = new ColumnDataInViewModel()
                {
                    Name = data[1],
                    MaxMark = Int32.Parse(data[2]),
                    Rating = data[3] == "1" ? true : false,
                    Summary = data[4] == "1" ? true : false
                };
                result.Add(col);
            }
            return result;
        }

        public ActionResult ListDocuments()
        {
            return View(AppDb.Documents.ToList());
        }

        public ActionResult DeleteDocument(int id)
        {
            return RedirectToAction("ListDocuments");
        }
	}
}